/*
  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the
  MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

  Copyright Buildbot Team Members
*/

import {describe, expect, it} from 'vitest';
import {
  capitalize,
  copyOrSplit,
  emailInString,
  endpointPath,
  numberOrString,
  parse,
  restPath,
  socketPath,
  socketPathRE,
} from './DataUtils';

describe('Data utils service', function () {
  describe('capitalize(string)', () =>
    it('should capitalize the parameter string', function () {
      let result = capitalize('test');
      expect(result).toBe('Test');

      result = capitalize('t');
      expect(result).toBe('T');
    }));

  describe('socketPath(arg)', () =>
    it('should return the WebSocket subscribe path of the parameter path', function () {
      let result = socketPath('asd/1/bnm');
      expect(result).toBe('asd/1/bnm/*/*');

      result = socketPath('asd/1');
      expect(result).toBe('asd/1/*');
    }));

  describe('socketPathRE(arg)', () =>
    it('should return the WebSocket subscribe path of the parameter path', function () {
      const result = socketPathRE('asd/1/*');
      expect(result.test('asd/1/new')).toBeTruthy();

      let source = socketPathRE('asd/1/bnm/*/*').source;
      expect(['^asd\\/1\\/bnm\\/[^\\/]+\\/[^\\/]+$', '^asd\\/1\\/bnm\\/[^/]+\\/[^/]+$']).toContain(
        source,
      );

      source = socketPathRE('asd/1/*').source;
      expect(['^asd\\/1\\/[^\\/]+$', '^asd\\/1\\/[^/]+$']).toContain(source);
    }));

  describe('restPath(arg)', () =>
    it('should return the rest path of the parameter WebSocket subscribe path', function () {
      let result = restPath('asd/1/bnm/*/*');
      expect(result).toBe('asd/1/bnm');

      result = restPath('asd/1/*');
      expect(result).toBe('asd/1');
    }));

  describe('endpointPath(arg)', () =>
    it('should return the endpoint path of the parameter rest or WebSocket path', function () {
      let result = endpointPath('asd/1/bnm/*/*');
      expect(result).toBe('asd/1/bnm');

      result = endpointPath('asd/1/*');
      expect(result).toBe('asd');
    }));

  describe('copyOrSplit(arrayOrString)', function () {
    it('should copy an array', function () {
      const array = [1, 2, 3];
      const result = copyOrSplit(array);
      expect(result).not.toBe(array);
      expect(result).toEqual(array);
    });

    it('should split a string', function () {
      const string = 'asd/123/bnm';
      const result = copyOrSplit(string);
      expect(result).toEqual(['asd', '123', 'bnm']);
    });
  });

  describe('parse(object)', () =>
    it('should parse fields from JSON', function () {
      const test = {
        a: 1,
        b: 'asd3',
        c: JSON.stringify(['a', 1, 2]),
        d: JSON.stringify({asd: [], bsd: {}}),
      };

      const copy = JSON.parse(JSON.stringify(test));
      copy.c = JSON.stringify(copy.c);
      copy.d = JSON.stringify(copy.d);

      const parsed = parse(test);

      expect(parsed).toEqual(test);
    }));

  describe('numberOrString(string)', function () {
    it('should convert a string to a number if possible', function () {
      const result = numberOrString('12');
      expect(result).toBe(12);
    });

    it('should throw if it is not a number', function () {
      expect(() => numberOrString('w3as')).toThrow();
    });
  });

  describe('emailInString(string)', () =>
    it('should return an email from a string', function () {
      let email = emailInString('foo <bar@foo.com>');
      expect(email).toBe('bar@foo.com');
      email = emailInString('bar@foo.com');
      expect(email).toBe('bar@foo.com');
    }));
});
